﻿using System;
using System.Linq;
using System.Xml.Linq;

namespace Serious.SweetConfig
{
	/// <summary>
	/// Responsible for building the ParameterList
	/// </summary>
	public class ParameterListBuilder
	{
		/// <summary>
		/// Creates and builds a ParameterList instance from the given paramter and environment values xml documents
		/// </summary>
		/// <param name="parameterXml">XDocument instance containing the parameters xml</param>
		/// <param name="environmentXml">XDocument instance containing the setParameters (environment values) xml</param>
		/// <returns>Instance of a ParameterList</returns>
		/// <exception cref="System.ArgumentNullException">Thrown if either parameterXml or environmentXml is null</exception>
		public ParameterList BuildParameterList(XDocument parameterXml, XDocument environmentXml)
		{
			if (parameterXml == null)
			{
				throw new ArgumentNullException("parameterXml");
			}

			if (environmentXml == null)
			{
				throw new ArgumentNullException("environmentXml");
			}

			ParameterList parameters = new ParameterList();
			
			parameters.AddRange(
				from item in parameterXml.Descendants("parameter")
				where item.Descendants("parameterEntry").Any(pe => (string)pe.Attribute("kind") == "XmlFile")
                select new Parameter
                {
					Name = (string)item.Attribute("name"),
                    Description = (string)item.Attribute("description"),
                    DefaultValue = (string)item.Attribute("defaultValue"),
					Tags = (string)item.Attribute("tags"),
					Match = (string)item.Descendants("parameterEntry")
						.First(pe => (string)pe.Attribute("kind") == "XmlFile").Attribute("match"),
					Value = GetEnvironmentValue(environmentXml, (string)item.Attribute("name"), (string)item.Attribute("defaultValue"))
                }
			);

			return parameters;
		}

		private static string GetEnvironmentValue(XDocument environmentXml, string name, string defaultValue)
		{
			var setParamter = environmentXml.Descendants("setParameter")
				.FirstOrDefault(sp => (string)sp.Attribute("name") == name);

			return setParamter == null ? defaultValue : (string)setParamter.Attribute("value");
		}
	}
}
